/*********************************************************************************
 *      Copyright:  (C) 2022 guoyi 
 *                  All rights reserved.
 *
 *       Filename:  ppp.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(23/05/21)
 *         Author:  guoyi<675088383@qq.com>
 *      ChangeLog:  1, Release initial version on "22/05/15 15:02:38"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>

#include "atcmd.h"
#include "ping.h"
#include "logger.h"


int check_iface_exist(char *iface)
{
    char       *nic_path = "/sys/class/net/";
    char        nicpath[64];
    int         rv = -2;

    memset(nicpath, 0, sizeof(nicpath));

    sprintf(nicpath, "%s%s", nic_path, iface);
    rv = access(nicpath, 0);
    if( rv == 0 )
    {
        return 1;
    }
    else
        return 0;
}

int check_iface_ipaddr(char *iface, char *ipaddr, int size)
{
    char       *ifconfig = "ifconfig ";
    char        cmd[64];
    char        buf[128];
    FILE       *fp;

    memset(cmd, 0, sizeof(cmd));
    memset(buf, 0, sizeof(buf));

    sprintf(cmd, "%s%s | grep inet", ifconfig, iface);

    fp = popen(cmd, "r");
    fgets(buf, sizeof(buf), fp);

    if( strstr(buf, "error") )
    {
        return -1;
    }
    else
    {
        if( ( 0==at_fetch(buf, "inet", "netmask", ipaddr, size) ) 
         || ( 0==at_fetch(buf, "addr:", "P-t-P", ipaddr, size)) )
        {
            log_nrml("find %s id :%s\n", iface, ipaddr);
            return 0;
        }
    }

    return -1;
}

/* *************************************************************
 * 功能:
 * 做ping测试, 看网络通不通
 *
 * 参数:
 * iface        :   网卡名字  
 * ping_addr    :   IP或域名 
 *
 * 返回值:
 * rv = 0 网络通;     rv = -1 网络不通 
 * ************************************************************/
int ping_test(char *iface, char *ping_addr)
{
    int         rv = -1;
    FILE       *fp;
    char        cmd[512];
    char        buf[512];
    char        rbuf[512];

    memset(cmd, 0, sizeof(cmd));
    memset(buf, 0, sizeof(buf));
    memset(rbuf, 0, sizeof(rbuf));

    //sprintf(cmd, "ping %s -I %s -c 4 -w 1 -s 1 -i 0.5", ping_addr, iface);
    sprintf(cmd, "ping %s -I %s -c 4", ping_addr, iface);
   
    fp = popen(cmd, "r");
    while(fgets(buf, sizeof(buf), fp) != NULL)
    {
        if( at_fetch(buf, "received,", "%", rbuf, sizeof(rbuf)) == 0 )
        {
            if( atoi(rbuf) < 80 )
            {
                rv = 0;
                log_nrml("%s network card has network, packet loss rate : %d\n", iface, atoi(rbuf));
            }
            else 
            {
                rv = -1;
                log_nrml("%s network card without network, packet loss rate : %d\n", iface, atoi(rbuf));
            }
        }
    }
    return rv;
}


int check_nic_priority(conf_t *conf)
{
    int             i = 0, j = 0, k = 0, number = 0, rv = -2;
    static int      now_time = -1;
    static int      start_time = -1; 
    struct timeval  tv; 
    static char     ping_status[5];
    char           *priority[5] = {0};
    char           *p = NULL;

    p = strtok(conf->ifaces, ",");
    while( p )
    {
        priority[i++] = p;
        p = strtok(NULL, ",");
    }

    gettimeofday(&tv, NULL);
    now_time = tv.tv_sec;

    if( start_time == -1 || (now_time - start_time) > conf->timeout )
    {
        memset(ping_status, 0, sizeof(ping_status));
        gettimeofday(&tv, NULL);
        start_time = tv.tv_sec;

        for(j=0; j<i; j++)
        {
            /*  判断网卡是否存在 */
            rv = check_iface_exist(priority[j]);
            if( 1 == rv )
            {
                /*  网卡做ping测试 */ 
                if( 0 == ping_test(priority[j], conf->pingaddr) )
                {
                    ping_status[j] = 1;
                }

            }
        }

        for(k=0; k<j-1; k++)
        {
            if( ping_status[k] == 1 )
            {
                number++;
            }
        }
        if( number > 0 && ping_status[j] == 1 )
        {
            /*  此时为4G拨号成功, 并且有线或无线网卡恢复上网, 则需要断开4G拨号 */
            rv = 2;
        }
        else if( number == 0 && ping_status[j] == 0 )
        {
            /*  此时为4G未拨号, 并且有线和无线网卡也没有网络, 则需要启动4G拨号 */
            rv = 1;
        }
        else
        {
            /*  此时4G和(有线或无线)就有一个正在上网, 则4G拨号状态不做改变  */
            rv = 0;
        }

    }
    return rv;
}
